home *** CD-ROM | disk | FTP | other *** search
/ MacFormat España 15 / macformat_15.iso / Shareware Internet / Ciencia / CFG 2.3 (Shareware) / µCinema Converter / preferences.c < prev    next >
Text File  |  1994-04-02  |  13KB  |  601 lines

  1. /********************************************************************
  2.     µCinema Converter 1.0
  3.     module: preferences.c
  4.     April 1994
  5.     by John A. Schlack
  6.  ********************************************************************/
  7.  
  8.  
  9. #include "constants.h"
  10. #include "preferences.h"
  11. #include "µCinema.h"
  12.  
  13.  
  14. /* --------------------------------------------------------------------------------- */
  15.  
  16.  
  17. /* preferences resource */
  18.  
  19. #define PREFS_RTYPE            'pref'
  20. #define PREFS_ID            1000
  21.  
  22.  
  23. /* STR# for preferences dialog */
  24.  
  25. #define FRAME_RATE_SET        128
  26. #define PREFERENCES_SET        129
  27. #define STRN_TITLE            1
  28. #define STRN_PROMPT            2
  29.  
  30.  
  31. /* preferences dialog */
  32.  
  33. #define PREFERENCES_DIALOG    129
  34. #define FPS_POPUP_ITEM        5
  35. #define FPS_LABEL_ITEM        4
  36. #define PREFS_TITLE            3
  37. #define PREFS_PROMPT        6
  38. #define PREF_POPUP_MENU_ID    5
  39. #define OTHER_FPS_ITEM        7
  40.  
  41.  
  42. /* custom frame rate dialog */
  43.  
  44. #define FRAME_RATE_DIALOG    130
  45. #define FRAME_EDIT_BOX        4
  46.  
  47.  
  48. /* general constants */
  49.  
  50. #define DEFAULT_FPS            10
  51.  
  52. #define returnKey            13
  53. #define enter                3
  54. #define esc                    27
  55. #define pushButton            (ctrlItem + btnCtrl)
  56.  
  57.  
  58. /* --------------------------------------------------------------------------------- */
  59.  
  60.  
  61. typedef struct PREFS_STRUCT
  62. {
  63.     short    framesPerSecond;
  64. } PREFS_STRUCT;
  65.  
  66.  
  67. /* --------------------------------------------------------------------------------- */
  68.  
  69.  
  70. static PREFS_STRUCT        rPrefs;
  71. static short            rFramesChoice;
  72. static short            rFrames;
  73.  
  74.  
  75. /* --------------------------------------------------------------------------------- */
  76.  
  77.  
  78. /* Private Function Prototypes */
  79.  
  80. static Boolean    verifyPreferences( PREFS_STRUCT * prefs );
  81. static pascal void    updatePopupMenu( DialogPtr dialog, short item );
  82. static void        hiliteItem( Handle itemHandle, Boolean val );
  83. static void     outlineItem( DialogPtr theDialog, short theItem );
  84. static Handle     copyItemHandle( DialogPtr theDialog, short theItem );
  85. static void     invertLabel( DialogPtr dialog, short item );
  86. static void     copyItemRect( DialogPtr dialog, short item, Rect * r );
  87. static void     doPopup( DialogPtr dialog, short item, short menuID, short * choice );
  88. static void     drawTriangle( Rect * r );
  89. static void     setPopupDraw( short item, ProcPtr draw );
  90. static pascal Boolean prefsDialogFilter( DialogPtr whichDialog, EventRecord * event,
  91.                     short * itemHit );
  92. static Boolean     userFPSDialog( short * framesPerSecond );
  93.  
  94.  
  95. /* --------------------------------------------------------------------------------- */
  96.  
  97.  
  98. void loadPreferences( void )
  99. {
  100.     Handle    prefHand;
  101.     Boolean    useDefault = true;
  102.     
  103.     prefHand = (Handle) GetResource( PREFS_RTYPE, PREFS_ID );
  104.     if (prefHand != nil)
  105.     {
  106.         LoadResource( prefHand );
  107.         if (SizeResource( prefHand ) == sizeof( rPrefs ))
  108.         {
  109.             HLock( prefHand );
  110.             rPrefs = *((PREFS_STRUCT *) (*prefHand));
  111.             HUnlock( prefHand );
  112.             if (verifyPreferences( &rPrefs ))
  113.                 useDefault = false;
  114.         }
  115.         ReleaseResource( prefHand );
  116.     }
  117.     
  118.     if (useDefault)
  119.         rPrefs.framesPerSecond = DEFAULT_FPS;
  120. }
  121.  
  122.  
  123. /* -------------------------------------------------------------------------------- */
  124.  
  125.  
  126. void savePreferences( void )
  127. {
  128.     Handle             prefHand;
  129.     PREFS_STRUCT *    pp = &rPrefs;
  130.     
  131.     prefHand = (Handle) GetResource( PREFS_RTYPE, PREFS_ID );
  132.     if (prefHand != nil)
  133.     {
  134.         SetHandleSize( prefHand, sizeof( PREFS_STRUCT ) );
  135.         if (MemError() == noErr)
  136.         {
  137.             HLock( prefHand );
  138.             BlockMove( (char *) pp, (char *) (*prefHand), sizeof( PREFS_STRUCT ) );
  139.             HUnlock( prefHand );
  140.             ChangedResource( prefHand );
  141.             WriteResource( prefHand );
  142.         }
  143.         ReleaseResource( prefHand );
  144.     }
  145.     else if (PtrToHand( (Ptr) pp, &prefHand, sizeof( PREFS_STRUCT ) ) == noErr)
  146.     {
  147.         AddResource( prefHand, PREFS_RTYPE, PREFS_ID, "\pPreferences" );
  148.         if (ResError() == noErr)
  149.         {
  150.             WriteResource( prefHand );
  151.             ReleaseResource( prefHand );
  152.         }
  153.     }
  154.     else
  155.         return;
  156. }
  157.  
  158.  
  159. /* --------------------------------------------------------------------------------- */
  160.  
  161.  
  162. static Boolean verifyPreferences( PREFS_STRUCT * prefs )
  163. {
  164.     if ((prefs->framesPerSecond < 1) || (prefs->framesPerSecond > 60))
  165.         return false;
  166.     return true;
  167. }
  168.  
  169.  
  170. /* --------------------------------------------------------------------------------- */
  171.  
  172.  
  173. Boolean preferencesDialog( short * framesPerSecond )
  174. {
  175.     Str255            text;
  176.     DialogPtr        theDialog;
  177.     GrafPtr            old;
  178.     Handle            itemHandle;
  179.     short            itemHit, promptSet;
  180.     Boolean            dialogDone = false, error = false;
  181.  
  182.     theDialog = GetNewDialog( PREFERENCES_DIALOG, nil, (WindowPtr) -1 );
  183.     if (theDialog == nil)
  184.         return false;
  185.  
  186.     GetPort( &old );
  187.     SetPort( theDialog );
  188.     
  189.     promptSet = (framesPerSecond != nil) ? FRAME_RATE_SET : PREFERENCES_SET;
  190.     rFrames = rPrefs.framesPerSecond;
  191.     switch( rFrames )
  192.     {
  193.         case 8:  rFramesChoice = 1; break;
  194.         case 10: rFramesChoice = 2; break;
  195.         case 12: rFramesChoice = 3; break;
  196.         case 15: rFramesChoice = 4; break;
  197.         case 30: rFramesChoice = 5; break;
  198.         default: rFramesChoice = 7; break;
  199.     }
  200.     
  201.     GetIndString( &(text[0]), promptSet, STRN_TITLE );
  202.     itemHandle = copyItemHandle( theDialog, PREFS_TITLE );
  203.     if (itemHandle != nil)
  204.         SetIText( itemHandle, text );
  205.     else
  206.         error = true;
  207.     
  208.     if (!error)
  209.     {
  210.         GetIndString( &(text[0]), promptSet, STRN_PROMPT );
  211.         itemHandle = copyItemHandle( theDialog, PREFS_PROMPT );
  212.         if (itemHandle != nil)
  213.             SetIText( itemHandle, text );
  214.         else
  215.             error = true;
  216.     }
  217.     
  218.     if (error)
  219.     {
  220.         SetPort( old );
  221.         DisposDialog( theDialog );
  222.         return false;
  223.     }
  224.     
  225.     setPopupDraw( FPS_POPUP_ITEM, (ProcPtr) updatePopupMenu );
  226.     ShowWindow( theDialog );
  227.  
  228.     while (!dialogDone)
  229.     {
  230.         ModalDialog( prefsDialogFilter, &itemHit );
  231.         switch( itemHit )
  232.         {
  233.             case ok:
  234.             case cancel:
  235.                 dialogDone = true;
  236.                 break;
  237.  
  238.             case FPS_POPUP_ITEM:
  239.                 invertLabel( theDialog, FPS_LABEL_ITEM );
  240.                 doPopup( theDialog, FPS_POPUP_ITEM, PREF_POPUP_MENU_ID, &rFramesChoice );
  241.                 invertLabel( theDialog, FPS_LABEL_ITEM );
  242.                 switch( rFramesChoice )
  243.                 {
  244.                     case 1: rFrames =  8; break;
  245.                     case 2: rFrames = 10; break;
  246.                     case 3: rFrames = 12; break;
  247.                     case 4: rFrames = 15; break;
  248.                     case 5: rFrames = 30; break;
  249.                 }
  250.                 break;
  251.         }
  252.     }
  253.     SetPort( old );
  254.     DisposDialog( theDialog );
  255.     
  256.     if (framesPerSecond != nil)
  257.         *framesPerSecond = rFrames;
  258.     else
  259.     {
  260.         rPrefs.framesPerSecond = rFrames;
  261.         installProgramStatus( PS_PREFS_DIRTY );
  262.     }
  263.     
  264.     return (itemHit == ok);
  265. }
  266.  
  267.  
  268. /* --------------------------------------------------------------------------------- */
  269.  
  270.  
  271. static pascal void updatePopupMenu( DialogPtr dialog, short item )
  272. {
  273.     static unsigned char strAppend[] = "\p fps";
  274.  
  275.     MenuHandle    menu;
  276.     Str255        txt;
  277.     Rect        txtR, r;
  278.     short        i, j;
  279.  
  280.     NumToString( (long) rFrames, &(txt[0]) );
  281.     for (i=(short) txt[0]+1, j=1; j<=(short) strAppend[0]; i++, j++)
  282.         txt[i] = strAppend[j];
  283.     txt[0] += 4;
  284.  
  285.     copyItemRect( dialog, item, &r );
  286.     menu = (MenuHandle) (GetResource( 'MENU', PREF_POPUP_MENU_ID ));
  287.     if (menu != nil)
  288.     {
  289.         txtR = r;
  290.         txtR.left = txtR.left + 12;
  291.         txtR.right = txtR.right - 20;
  292.         TextBox( &txt[1], txt[0], &txtR, teJustLeft );
  293.         ReleaseResource( (Handle) menu );
  294.     }
  295.  
  296.     drawTriangle( &r );
  297.     r.right  = r.right  - 1;
  298.     r.bottom = r.bottom - 1;
  299.     FrameRect( &r );
  300.     MoveTo( r.right, r.top + 2 );
  301.     LineTo( r.right, r.bottom );
  302.     LineTo( r.left + 2, r.bottom );
  303. }
  304.  
  305.  
  306. /* --------------------------------------------------------------------------------- */
  307.  
  308.  
  309. static void hiliteItem( Handle itemHandle, Boolean val )
  310. {
  311.     if (!val)
  312.         HiliteControl( (ControlHandle) itemHandle, 255 );
  313.     else
  314.         HiliteControl( (ControlHandle) itemHandle, 0 );
  315. }
  316.  
  317.  
  318. /* --------------------------------------------------------------------------------- */
  319.  
  320.  
  321. static void outlineItem( DialogPtr theDialog, short theItem )
  322. {
  323.     short            type;
  324.     Rect            box;
  325.     Handle            itemHdl;
  326.     GrafPtr            oldGrafPtr;
  327.     
  328.     GetPort( &oldGrafPtr );
  329.     SetPort( theDialog );
  330.     GetDItem( theDialog, theItem, &type, &itemHdl, &box );
  331.     PenSize( 3, 3 );
  332.     InsetRect( &box, -4, -4 );
  333.     FrameRoundRect( &box, 16, 16 );
  334.     PenNormal();
  335.     SetPort( oldGrafPtr );    
  336. }
  337.  
  338.  
  339. /* --------------------------------------------------------------------------------- */
  340.  
  341.  
  342. static Handle copyItemHandle( DialogPtr theDialog, short theItem )
  343. {
  344.     Handle        item;
  345.     short        itemType;
  346.     Rect        box;
  347.     
  348.     GetDItem( theDialog, theItem, &itemType, &item, &box );
  349.     return item;
  350. }
  351.  
  352.  
  353. /* --------------------------------------------------------------------------------- */
  354.  
  355.  
  356. static void invertLabel( DialogPtr dialog, short item )
  357. {
  358.     Rect    r;
  359.  
  360.     /* Correct GrafPtr is assumed set. */
  361.  
  362.     copyItemRect( dialog, item, &r );
  363.     InvertRect( &r );
  364. }
  365.  
  366.  
  367. /* --------------------------------------------------------------------------------- */
  368.  
  369.  
  370. static void copyItemRect( DialogPtr dialog, short item, Rect * r )
  371. {
  372.     Handle        itemHandle;
  373.     short        itemType;
  374.  
  375.     GetDItem( dialog, item, &itemType, &itemHandle, r );
  376. }
  377.  
  378.  
  379. /* --------------------------------------------------------------------------------- */
  380.  
  381.  
  382. static void doPopup( DialogPtr dialog, short item, short menuID, short * choice )
  383. /*
  384.     Correct GrafPtr is assumed set.
  385. */
  386. {
  387.     GrafPtr        old;
  388.     MenuHandle    menu;
  389.     Rect        r, triangle;
  390.     long        result;
  391.     Point        corner;
  392.     short        newChoice, newFrame;
  393.  
  394.     GetPort( &old );
  395.     SetPort( dialog );
  396.     
  397.     copyItemRect( dialog, item, &r );
  398.     menu = GetMenu( menuID );
  399.     if (menu != NULL)
  400.     {
  401.         InsertMenu( menu, -1 );
  402.         triangle.top = r.top + 5;
  403.         triangle.left = r.right - 18;
  404.         triangle.bottom = triangle.top + 7;
  405.         triangle.right = triangle.left + 13;
  406.         EraseRect( &triangle );
  407.         corner.h = r.left;
  408.         corner.v = r.top;
  409.         LocalToGlobal( &corner );
  410.         CheckItem(menu, *choice, true);
  411.         result = PopUpMenuSelect (menu, corner.v, corner.h + 1, *choice);
  412.         CheckItem(menu, *choice, false);
  413.         DeleteMenu(menuID);
  414.         ReleaseResource( (Handle) menu );
  415.         InvalRect( &triangle );
  416.         
  417.         if (HiWord (result) != 0)
  418.         {
  419.             newChoice = LoWord( result );
  420.             if (newChoice == OTHER_FPS_ITEM)
  421.             {
  422.                 newFrame = rFrames;
  423.                 if (userFPSDialog( &newFrame ))
  424.                 {
  425.                     rFrames = newFrame;
  426.                     InsetRect( &r, 1, 1 );
  427.                     InvalRect( &r );
  428.                     *choice = newChoice;
  429.                 }
  430.             }
  431.             else if (newChoice != *choice)
  432.             {
  433.                 *choice = newChoice;
  434.                 InsetRect( &r, 1, 1 );
  435.                 InvalRect( &r );
  436.             }
  437.         }
  438.     }
  439.     
  440.     SetPort( old );
  441. }
  442.  
  443.  
  444. /* --------------------------------------------------------------------------------- */
  445.  
  446.  
  447. static void drawTriangle( Rect * r )
  448. /*
  449.     Correct GrafPtr is assumed set.
  450. */
  451. {
  452.     PolyHandle    tri;
  453.  
  454.     tri = OpenPoly ();
  455.     MoveTo( r->right - 15, r->top + 5 );
  456.     Line (5, 5);
  457.     Line (5, -5);
  458.     Line (-10, 0);
  459.     ClosePoly ();
  460.     FillPoly( tri, (ConstPatternParam) (&qd.black) );
  461.     KillPoly( tri );
  462. }
  463.  
  464.  
  465. /* --------------------------------------------------------------------------------- */
  466.  
  467.  
  468. static void setPopupDraw( short item, ProcPtr draw )
  469. {
  470.     Handle    itemHandle;
  471.     Rect    itemRect;
  472.     short    itemType;
  473.  
  474.     GetDItem (qd.thePort, item, &itemType, &itemHandle, &itemRect);
  475.     SetDItem (qd.thePort, item, itemType, (Handle) draw, &itemRect);
  476. }
  477.  
  478.  
  479. /* --------------------------------------------------------------------------------- */
  480.  
  481.  
  482. static pascal Boolean prefsDialogFilter( DialogPtr whichDialog, EventRecord * event,
  483.     short * itemHit )
  484. {
  485.     Handle            itemHandle;
  486.     Rect            itemRect;
  487.     long            finalTicks;
  488.     short            itemType, prevEdit;
  489.     Boolean            filtered;
  490.     char            key;
  491.  
  492.     filtered = false;
  493.     switch ((*event).what)
  494.     {
  495.         case keyDown:
  496.         case autoKey:
  497.             key = (*event).message & charCodeMask;
  498.             if ((key == returnKey) || (key == enter) || (key == esc)
  499.                 || ((key == '.') && (((*event).modifiers & cmdKey) != 0)))
  500.             {
  501.                 if ((key == returnKey) || (key == enter))
  502.                     *itemHit = ok;
  503.                 else
  504.                     *itemHit = cancel;
  505.                 GetDItem (whichDialog, *itemHit, &itemType, &itemHandle, &itemRect);
  506.                 if ((itemType & itemDisable) == 0)
  507.                 {
  508.                     if ((itemType & (255 - itemDisable)) == pushButton)
  509.                     {
  510.                         HiliteControl ((ControlHandle) itemHandle, inButton);
  511.                         Delay (8, &finalTicks);
  512.                         HiliteControl ((ControlHandle) itemHandle, 0);
  513.                     }
  514.                     filtered = true;
  515.                 }
  516.             }
  517.             break;
  518.  
  519.         case updateEvt:
  520.             if ((WindowPtr) (*event).message == qd.thePort)
  521.             {
  522.                 GetDItem (whichDialog, ok, &itemType, &itemHandle, &itemRect);
  523.                 if ((itemType & (255 - itemDisable)) == pushButton)
  524.                     outlineItem( whichDialog, ok );
  525.             }
  526.             break;
  527.     }
  528.     return filtered;
  529. }
  530.  
  531.  
  532. /* --------------------------------------------------------------------------------- */
  533.  
  534.  
  535. static Boolean userFPSDialog( short * framesPerSecond )
  536. {
  537.     Str255            text;
  538.     DialogPtr        theDialog;
  539.     GrafPtr            old;
  540.     Handle            editTextHandle;
  541.     long            fps;
  542.     short            itemHit;
  543.     Boolean            dialogDone = false;
  544.  
  545.     theDialog = GetNewDialog( FRAME_RATE_DIALOG, nil, (WindowPtr) -1 );
  546.     if (theDialog == nil)
  547.         return false;
  548.  
  549.     GetPort( &old );
  550.     SetPort( theDialog );
  551.     
  552.     NumToString( (long) *framesPerSecond, text );
  553.     editTextHandle = copyItemHandle( theDialog, FRAME_EDIT_BOX );
  554.     if (editTextHandle != nil)
  555.     {
  556.         SetIText( editTextHandle, text );
  557.         SelIText( theDialog, FRAME_EDIT_BOX, 0, 32767 );
  558.     }
  559.     else
  560.     {
  561.         SetPort( old );
  562.         DisposDialog( theDialog );
  563.         return false;
  564.     }
  565.     ShowWindow( theDialog );
  566.  
  567.     while (!dialogDone)
  568.     {
  569.         ModalDialog( prefsDialogFilter, &itemHit );
  570.         switch( itemHit )
  571.         {
  572.             case ok:
  573.                 GetIText( editTextHandle, text );
  574.                 StringToNum( text, &fps );
  575.                 if ((fps < 1L) || (fps > 60L))
  576.                     errorHandler( ERR_FRAME_RATE );
  577.                 else
  578.                 {
  579.                     *framesPerSecond = (short) fps;
  580.                     dialogDone = true;
  581.                 }
  582.                 break;
  583.             case cancel:
  584.                 dialogDone = true;
  585.                 break;
  586.         }
  587.     }
  588.     SetPort( old );
  589.     DisposDialog( theDialog );
  590.     return (itemHit == ok);
  591. }
  592.  
  593.  
  594. /* --------------------------------------------------------------------------------- */
  595.  
  596.  
  597. short copyPrefsFPS( void )
  598. {
  599.     return rPrefs.framesPerSecond;
  600. }
  601.